package Risk.Moteur;

import java.awt.Color;

import java.io.Serializable;

import java.util.ArrayList;

/**
 *  Joueur
 *     @version    1.0, 07/12/26
 *   @author     Alexandre LIGUORI
 */
public class Joueur implements Serializable {

    /**
     * erreur
     */
    public static int	ERREUR = -1;

    // Sebastien : Ajout d'un champ pour securiser la serialisation
    private static final long	serialVersionUID = 14L;
    private ArrayList<Carte>	cartesEnMain;
    private Color		couleur;
    private String		nom;
    private int			reserveArmee;

    /**
     *  Constructeur de joueur
     *
     * @param nom nom du joueur
     * @param couleur couleur du joueur
     */
    public Joueur(String nom, Color couleur) {
	this.nom          = nom;
	this.cartesEnMain = new ArrayList<Carte>();
	this.couleur      = couleur;
	this.reserveArmee = 0;
    }

    /**
     * ajoute une carte bonus a la main du joueur
     * @param cb la carte
     * @return true si reussi, false sinon
     */
    public boolean ajouteCarteBonus(Carte cb) {
	return this.cartesEnMain.add(cb);
    }

    /**
     * Retire un soldat du pays courrant,  si c est possible
     * @return 1 si le soldat est retire, 0 sinon
     */
    public int decrementeReserveArmee() {
	if (reserveArmee > 0) {
	    reserveArmee--;

	    return 1;
	}

	System.out.println("Votre reserve de soldat est vide.");

	return 0;
    }

    /**
     * retire un carte en main
     * @param cb la carte
     * @return true si reussi, false sinon
     */
    public boolean retireCartesBonus(Carte cb) {
	return this.cartesEnMain.remove(cb);
    }

    /**
     * retire les cartes en main
     * @param tab tableau de trois indices
     * @return true si reussi, false sinon
     */
    public boolean retireCartesEnMain(int[] tab) {
	Carte	carte_TMP1 = null;
	Carte	carte_TMP2 = null;
	Carte	carte_TMP3 = null;

	if (tab.length != 3) {
	    System.out.println("Erreur dans retireCartesEnMain : passer 3 indices de cartes en parametres");

	    return false;
	}

	carte_TMP1 = cartesEnMain.get(tab[ 0 ]);
	carte_TMP2 = cartesEnMain.get(tab[ 1 ]);
	carte_TMP3 = cartesEnMain.get(tab[ 2 ]);

	if (!retireCartesBonus(carte_TMP1) ||!retireCartesBonus(carte_TMP2) ||!retireCartesBonus(carte_TMP3)) {
	    System.out.println("Erreur dans retireCartesEnMain");

	    return false;
	}

	return true;
    }

    /**
     * Test si au moins une des cartes de la combinaison correspond
     * a un pays controole par ce joueur ; si ok, +2 armees sinon rien
     * @param combinaison combinaison de carte
     * @return le nombre d armees en bonus
     */
    private int testBonusCartes(ArrayList<Carte> combinaison) {
	for (Carte c : combinaison) {
	    if (c.getPays().controlePays(this)) {
		System.out.println("BONUS (+ 2 soldats) : vous possedez " + c.getPays());

		return 2;
	    }
	}

	return 0;
    }

    /**
     * test une combinaison de carte
     * @param combinaison la liste des cartes a testees
     * @return la valeur de la coombinaison (ERREUR si aucune)
     */
    private int testCombinaisonCartes(ArrayList<Carte> combinaison) {

	// 3 fantassin
	if (combinaison.get(0).getValeur().equals("fantassin") && combinaison.get(1).getValeur().equals("fantassin")
		&& combinaison.get(2).getValeur().equals("fantassin")) {
	    System.out.println("+ 3 soldats");

	    return 3;
	}

	// 3 cavaliers
	if (combinaison.get(0).getValeur().equals("cavalier") && combinaison.get(1).getValeur().equals("cavalier")
		&& combinaison.get(2).getValeur().equals("cavalier")) {
	    System.out.println("+ 5 soldats");

	    return 5;
	}

	// 3 canons
	if (combinaison.get(0).getValeur().equals("canon") && combinaison.get(1).getValeur().equals("canon")
		&& combinaison.get(2).getValeur().equals("canon")) {
	    System.out.println("+ 8 soldats");

	    return 8;
	}

	// 1 de chaque
	if ((combinaison.get(0).getValeur().equals("fantassin") || combinaison.get(1).getValeur().equals(
		"fantassin") || combinaison.get(2).getValeur().equals("fantassin")) && (combinaison.get(
		0).getValeur().equals("cavalier") || combinaison.get(1).getValeur().equals(
		"cavalier") || combinaison.get(2).getValeur().equals("cavalier")) && (combinaison.get(
		0).getValeur().equals("canon") || combinaison.get(1).getValeur().equals("canon") || combinaison.get(
		2).getValeur().equals("canon"))) {
	    System.out.println("+ 10 soldats");

	    return 10;
	}

	return ERREUR;
    }

    /**
     * test si une liste d'indice (indiquant la position des cartes en main)
     * peut renvoyer une combinaison +
     * verification si une des cartes correspond a un pays du joueur courant (dans ce cas, +2 armees)
     * @param tab tableau de trois indices
     * @return la valeur de la combinaison (ERREUR si rien)
     */
    public int testDepenseCartes(int[] tab) {
	int			valeurRenfort = -1;
	ArrayList<Carte>	combinaison   = new ArrayList<Carte>();
	Carte			carte_TMP1    = null;
	Carte			carte_TMP2    = null;
	Carte			carte_TMP3    = null;

	if (cartesEnMain.size() < 3) {
	    System.out.println("Erreur dans depenseCartes : vous ne possedez pas assez de cartes en main");

	    return ERREUR;
	}

	if (tab.length != 3) {
	    System.out.println("Erreur dans depenseCartes : passer 3 indices de cartes en parametres");

	    return ERREUR;
	}

	carte_TMP1 = cartesEnMain.get(tab[ 0 ]);
	carte_TMP2 = cartesEnMain.get(tab[ 1 ]);
	carte_TMP3 = cartesEnMain.get(tab[ 2 ]);

	if ((carte_TMP1 == null) || (carte_TMP2 == null) || (carte_TMP3 == null)) {
	    System.out.println("Erreur dans depenseCartes : un (ou plusieurs) indice(s) est (sont) trop errone");

	    return ERREUR;
	}

	if ((carte_TMP1 == carte_TMP2) || (carte_TMP1 == carte_TMP3) || (carte_TMP2 == carte_TMP3)) {
	    System.out.println("Erreur dans depenseCartes : vous avez choisi une ou plusieur fois la meme carte");

	    return ERREUR;
	}

	combinaison.add(carte_TMP1);
	combinaison.add(carte_TMP2);
	combinaison.add(carte_TMP3);
	valeurRenfort = testCombinaisonCartes(combinaison);

	if (valeurRenfort == ERREUR) {
	    System.out.println("Erreur dans depenseCartes : aucune combinaison");

	    return ERREUR;
	}

	valeurRenfort += testBonusCartes(combinaison);

	return valeurRenfort;
    }

    /**
     * to string
     * @return string
     */
    @Override
    public String toString() {
	return nom;
    }

    /**
     * test si le joueur a trop de carte en main
     * @return true si le joueur possede trop de carte en main, false sinon
     */
    public boolean tropDeCartesEnMain() {
	if (cartesEnMain.size() >= 5) {
	    return true;
	}

	return false;
    }

    /**
     * renvoie la liste des carte en main
     * @return la liste des carte en main
     */
    public ArrayList<Carte> getCartesEnMain() {
	return cartesEnMain;
    }

    /**
     * renvoie la couleur du joueur
     * @return la couleur du joueur
     */
    public Color getCouleur() {
	return couleur;
    }

    /**
     * renvoie le nombre de carte en main
     * @return le nombre de carte en main
     */
    public int getNbCartes() {
	return this.cartesEnMain.size();
    }

    /**
     * renvoie le nom du joueur
     * @return le nom du joueur
     */
    public String getNom() {
	return nom;
    }

    /**
     * renvoie le nombre d armee a placer
     * @return le nombre d armee a placer
     */
    public int getReserveArmee() {
	return reserveArmee;
    }

    /**
     * mettre a jour le nombre d armee en reserve
     * @param reserveArmee le nouveau nombre d armee en reserve
     */
    public void setReserveArmee(int reserveArmee) {
	this.reserveArmee = reserveArmee;
    }
}
